# include <bits/stdc++.h>
# define MAXN 10033
using namespace std;

inline int gn() { 
    int k = 0, f = 1;
    char c = getc();
    for(; !isdigit(c); c = getc()) if(c == '-') f = -1;
    for(; isdigit(c); c = getc()) k = k * 10 + c - '0';
    return f * k;
}

struct edge { 
    int to, w;
    edge *ne;
    edge(){;}
    edge(int to_, int w_, edge *ne_) { 
        to = to_, w = w_, ne = ne_;
    }
}*head[MAXN];

inline void addedge(int fr, int to, int w) { 
    head[fr] = new edge(to, w, head[fr]);
    head[to] = new edge(fr, w, head[to]);
}

struct b_edge { 
    int fr, to, w;
    b_edge(){;}
    b_edge(int fr_, int to_, int w_) {fr = fr_, to = to_, w = w_;}
}be[MAXN];

int n, w[MAXN], d[MAXN], siz[MAXN], son[MAXN], fa[MAXN], dep[MAXN], q[MAXN], l, r;
int top[MAXN], dfn[MAXN], id;
char op[10];


inline void bfs() { 
    l = r = 1;
    q[l] = 1;
    while(l <= r) { 
        int u = q[l++];
        dep[u] = dep[fa[u]] + 1;
        siz[u] = 1; 
        for(edge *e = head[u]; e; e = e->ne) { 
            int v = e->to;
            if(siz[v]) continue;
            fa[v] = u;
            q[++r] = v;
        }
    }
    for(int i = r; i; i--) { 
        siz[fa[q[i]]] += siz[q[i]];
        son[fa[q[i]]] = (siz[q[i]] > siz[son[fa[q[i]]]]) ? q[i] : son[fa[q[i]]];
    }
}

void dfs(int x, int tp) { 
    dfn[x] = ++id;
    top[x] = tp;
    if(!son[x]) return;
    dfs(son[x], tp);
    for(edge *e = head[x]; e; e = e->ne) { 
        if(dfn[e->to]) continue;
        dfs(e->to, e->to);
    }
}

int M, mx[MAXN << 2];

inline void pushup(int x) { 
    mx[x] = max(mx[x << 1], mx[x << 1 | 1]);
}

inline void build() { 
    for(M = 1; M <= n + 1; M <<= 1);
    for(int i = 1; i <= n; i++) { 
        mx[i + M] = w[i];
    }
    for(int i = M - 1; i; i--) pushup(i);
}

inline void change(int x, int p) { 
    x += M;
    mx[x] = p;
    for(int i = x >> 1; i; i >>= 1) { 
        pushup(i);
    }
}

inline int query(int l, int r) { 
    int ans = 0;
    for(l += M -1, r += M + 1; l ^ r ^ 1; l >>= 1, r >>= 1) { 
        if(~l & 1) ans = max(ans, mx[l + 1]);
        if(r & 1) ans = max(ans, mx[r - 1]);
    }
   return ans;
}

inline int find(int u, int v) { 
# define tu top[u]
# define tv top[v]
    int ans = 0;
    while(tv ^ tu) { 
        if(dep[tu] < dep[tv]) swap(u, v);
        ans = max(ans, query(dfn[tu], dfn[u]));
        u = fa[tu];
    }
    if(u ^ v && dep[u] < dep[v]) swap(u, v);
    ans = max(ans, query(dfn[v] + 1, dfn[u]));
    return ans;
}

int main() { 
# ifndef LOCAL
    freopen("qtree.in", "r", stdin);
    freopen("qtree.out", "w", stdout);
# else 
    freopen("in", "r", stdin);
# endif
    n = gn();
    for(int i = 1, a, b, c; i < n; i++) { 
        a = gn();
        b = gn();
        c = gn();
        addedge(a, b, c);
        be[i] = b_edge(a, b, c);
    }
    bfs();
    dfs(1, 1);
    for(int i = 1; i <= n; i++) { 
        d[i] = (dep[be[i].fr] > dep[be[i].to]) ? be[i].fr : be[i].to;
        w[dfn[d[i]]] = be[i].w;
    }
    build();
    while(true) { 
        if(op == 'D') break;
        else if(op == 'Q') { 
            printf("%d\n", find(gn(), gn()));
        } else if(op == 'C') { 
            int l = gn();
            change(dfn[d[l]], gn());
        }
    }
}
